<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js coal">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>PWN Patch defense skill - Andrew&#x27;s Blog</title>


        <!-- Custom HTML head -->
        
        <meta name="description" content="Andrew Ryan&#x27;s Blog">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        <link rel="stylesheet" href="../../src/style/custom.css">

        <!-- MathJax -->
        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    </head>
    <body>
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('coal')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var html = document.querySelector('html');
            var sidebar = null;
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> Linux</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/Linux/git_cheatsheet.html"><strong aria-hidden="true">1.6.</strong> Git Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/Linux/bash_cheatsheet.html"><strong aria-hidden="true">1.7.</strong> Bash Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/macos/mac.html"><strong aria-hidden="true">2.</strong> MacOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/macos/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li><li class="chapter-item "><a href="../../posts/macos/macos_pwn_env_setup.html"><strong aria-hidden="true">2.2.</strong> macos pwn env setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> Swift</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in Swift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> iOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> Objective-C</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> Dart</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> Rust</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item "><a href="../../posts/rust/compress_rust_binary_size.html"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/how_to_create_yolov8_based_object_detection_web_service_using_python,_julia,_node.js,_javascript,_go_and_rust.html"><strong aria-hidden="true">7.25.</strong> How to create YOLOv8-based object detection web service using Python, Julia, Node.js, JavaScript, Go and Rust</a></li><li class="chapter-item "><a href="../../posts/rust/implment_builder_proc_macro_for_command_struct.html"><strong aria-hidden="true">7.26.</strong> implment Builder proc-macro for Command struct</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> Java</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> Python</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li><li class="chapter-item "><a href="../../posts/python/sanctum_model_yaml.html"><strong aria-hidden="true">9.5.</strong> sanctum model yaml</a></li><li class="chapter-item "><a href="../../posts/python/how_to_detect_objects_on_images_using_the_yolov8_neural_network.html"><strong aria-hidden="true">9.6.</strong> How to detect objects on images using the YOLOv8 neural network</a></li><li class="chapter-item "><a href="../../posts/python/use_huggingface_model.html"><strong aria-hidden="true">9.7.</strong> use huggingface model</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> Go</a></li><li class="chapter-item "><a href="../../posts/javascript/js.html"><strong aria-hidden="true">11.</strong> Javascript</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/javascript/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/javascript/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/javascript/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/javascript/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/javascript/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/javascript/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/javascript/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/javascript/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> Ruby</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item "><a href="../../posts/ruby/learn_ruby.html"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item "><a href="../../posts/ruby/ruby_note.html"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> React</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/react/react_life_cycle.html"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> Vue</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> Angular</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> Css</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> Php</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.</strong> Windows</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.1.</strong> Windows</a></li><li class="chapter-item "><a href="../../posts/windows/windows10_use_powershell_dedup_redundent_path.html"><strong aria-hidden="true">18.2.</strong> Windows10 use PowerShell dedup redundent PATH</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">19.</strong> Leetcode</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">19.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">19.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">19.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">19.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">19.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">19.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">19.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">19.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">20.</strong> CTF</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">20.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">20.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">20.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">20.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">20.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">20.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">20.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">20.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">20.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">20.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">20.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">20.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">20.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">20.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">20.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">20.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">20.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">20.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">20.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">20.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">20.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">20.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">20.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">20.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">20.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/zip_plain_text_attack.html"><strong aria-hidden="true">20.26.</strong> Zip plain text attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">20.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item expanded "><a href="../../posts/ctf/pwn_patch_defense_skill.html" class="active"><strong aria-hidden="true">20.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">20.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">20.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">20.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">20.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">20.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">20.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">20.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">20.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/pwnable_kr_challenge.html"><strong aria-hidden="true">20.37.</strong> Solutions for pwnable.kr</a></li><li class="chapter-item "><a href="../../posts/ctf/the_periodic_table.html"><strong aria-hidden="true">20.38.</strong> The Periodic Table</a></li><li class="chapter-item "><a href="../../posts/ctf/pwntools_cheatsheet.html"><strong aria-hidden="true">20.39.</strong> Pwntools Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/gdb_cheatsheet.html"><strong aria-hidden="true">20.40.</strong> GDB Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/iltes/iltes.html"><strong aria-hidden="true">21.</strong> ILTES</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/iltes/iltes_writing.html"><strong aria-hidden="true">21.1.</strong> ILTES Writing</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <!-- Track and set sidebar scroll position -->
        <script>
            var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
            sidebarScrollbox.addEventListener('click', function(e) {
                if (e.target.tagName === 'A') {
                    sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
                }
            }, { passive: true });
            var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
            sessionStorage.removeItem('sidebar-scroll');
            if (sidebarScrollTop) {
                // preserve sidebar scroll position when navigating via links within sidebar
                sidebarScrollbox.scrollTop = sidebarScrollTop;
            } else {
                // scroll sidebar to current active section when navigating via "next/previous chapter" buttons
                var activeSection = document.querySelector('#sidebar .active');
                if (activeSection) {
                    activeSection.scrollIntoView({ block: 'center' });
                }
            }
        </script>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Andrew&#x27;s Blog</h1>

                    <div class="right-buttons">
                        <a href="https://gitee.com/dnrops/dnrops" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="pwn-patch-defense-skill"><a class="header" href="#pwn-patch-defense-skill">PWN Patch defense skill</a></h1>
<h1 id="环境安装"><a class="header" href="#环境安装">环境安装</a></h1>
<ul>
<li>keypatch</li>
</ul>
<p><a href="https://github.com/keystone-engine/keypatch">https://github.com/keystone-engine/keypatch</a></p>
<p>将keypatch.py复制到 IDA 7.0\plugins</p>
<p>安装依赖Consolas</p>
<pre><code class="language-shell">pip install keystone-engine
pip install six
</code></pre>
<p><strong>Edit -&gt; Keypatch -&gt; Patcher</strong></p>
<p>选中一行指令patch，可以输入汇编代码 。</p>
<p><strong>Edit -&gt; Patch program -&gt; Apply patches to input file</strong></p>
<p>将修改保存到一个新的二进制文件（这是ida原本就有的功能）</p>
<p><strong>Edit -&gt; Keypatch -&gt; Search</strong></p>
<p>可以搜索汇编指令，不能直接搜索16进制，多条指令用 <code>;</code> 分隔</p>
<ul>
<li>lief</li>
</ul>
<pre><code class="language-shell">#python3
pip3 install lief

#python2
wget https://github.com/lief-project/LIEF/releases/download/0.9.0/lief-0.9.0-py2.7-linux.egg
cp ./lief-0.9.0-py2.7-linux.egg ~
pip install lief==0.9.0
</code></pre>
<p>API文档：https://lief-project.github.io/doc/latest/api/python/index.html</p>
<h1 id="patch技巧"><a class="header" href="#patch技巧">patch技巧</a></h1>
<h2 id="ida直接patch"><a class="header" href="#ida直接patch">IDA直接patch</a></h2>
<p>这种方式适合于较简单的修改，不能修改文件结构，直接使用**keypatch（快捷键Ctrl+Alt+k）**修改汇编代码，或者在Edit–&gt;Patch program–&gt;Assemble中进行修改：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094250.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094250.png" alt="img" /></a></p>
<p>例如这里存在<code>off-by-null</code>，直接将该指令nop掉即可：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094555.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094555.png" alt="img" /></a></p>
<p>如下图所示：
<a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094831.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411094831.png" alt="img" /></a></p>
<p>此时查看反编译的结果可以发现已经没有<code>off-by-null</code>漏洞了，最终还需要将修改的结果保存至文件中：
Edit–&gt;Patch program–&gt;Apply patches to input file</p>
<h2 id="使用lief"><a class="header" href="#使用lief">使用LIEF</a></h2>
<p>项目的地址：
<a href="https://github.com/lief-project/LIEF">https://github.com/lief-project/LIEF</a></p>
<h2 id="lief增加段来patch"><a class="header" href="#lief增加段来patch">LIEF增加段来patch</a></h2>
<p>程序的源代码如下：</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
int main(int argc, char** argv) {
  printf(&quot;/bin/sh%d&quot;,102);
  puts(&quot;let's go\n&quot;);
  printf(&quot;/bin/sh%d&quot;,102);
  puts(&quot;let's gogo\n&quot;);
  return EXIT_SUCCESS;
}
</code></pre>
<p><strong>目标是修改其中的printf函数为我们自己的函数</strong></p>
<h3 id="hook程序中的导入函数"><a class="header" href="#hook程序中的导入函数">hook程序中的导入函数</a></h3>
<h4 id="编写hook函数"><a class="header" href="#编写hook函数">编写hook函数</a></h4>
<p>首先要先编写我们的hook函数，编写hook函数有几个要求：</p>
<ul>
<li>汇编代码必须是位置独立的（也就是要使用-fPIC或-pie / -fPIE标志编译）</li>
<li>不要使用libc.so等外部库（使用：-nostdlib -nodefaultlibs flags）</li>
</ul>
<p>根据上面的限制条件，我们编译hook程序时使用的编译指令如下所示：</p>
<blockquote>
<p>gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook</p>
</blockquote>
<p>我们编写的hook函数<code>my_printf</code>如下：</p>
<pre><code class="language-c">void myprintf(char *a,int b){
    //AT&amp;T汇编格式
	asm(
		&quot;mov %rdi,%rsi\n&quot;
		&quot;mov $0,%rdi\n&quot;
		&quot;mov $0x20,%rdx\n&quot;
		&quot;mov $0x1,%rax\n&quot;
		&quot;syscall\n&quot;
		);
}
//gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook

// Intel汇编格式
// void myprintf(char *a,int b){
// 	asm(
// 		&quot;mov rsi, rdi;\n&quot;
// 		&quot;mov rdi, 0;\n&quot;
// 		&quot;mov rdx, 0x20;\n&quot;
// 		&quot;mov rax, 0x1;\n&quot;
// 		&quot;syscall;\n&quot;
// 		);
// }
//gcc -masm=intel -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
</code></pre>
<h4 id="将hook函数注入到程序并修改got表"><a class="header" href="#将hook函数注入到程序并修改got表">将hook函数注入到程序并修改got表</a></h4>
<pre><code class="language-python">import lief

binary = lief.parse(&quot;./vulner&quot;)
hook = lief.parse('./hook')
# inject hook program to binary
segment_added  = binary.add(hook.segments[0])

# hook got
my_printf      = hook.get_symbol(&quot;myprintf&quot;)
my_printf_addr = segment_added.virtual_address + my_printf.value

binary.patch_pltgot('printf', my_printf_addr)
binary.write('vulner.patched')
</code></pre>
<p>运行patch后的程序可以发现patch成功：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411190529.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411190529.png" alt="img" /></a></p>
<h3 id="hook指定地址的函数调用"><a class="header" href="#hook指定地址的函数调用">hook指定地址的函数调用</a></h3>
<p>使用下面的代码可以完成hook程序中指定地址的call函数调用：</p>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;amd64&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./vulner&quot;)
hook = lief.parse('./hook')
# inject hook program to binary
segment_added  = binary.add(hook.segments[0])
hook_fun      = hook.get_symbol(&quot;myprintf&quot;)

dstaddr = segment_added.virtual_address + hook_fun.value
srcaddr = 0x400584

patch_call(binary,srcaddr,dstaddr)

binary.write('vulner.patched')
</code></pre>
<h2 id="修改eh_frame段实现patch"><a class="header" href="#修改eh_frame段实现patch">修改.eh_frame段实现patch</a></h2>
<p><code>eh_frame</code>段在执行的时候对程序的影响不大，所以可以把hook代码添加到该段中，通过修改函数跳转的方式来执行hook代码</p>
<p>对section的操作参考<a href="https://lief.quarkslab.com/doc/latest/api/python/elf.html#section">官方文档-section部分</a></p>
<p>section对象中的content属性就是该section中的内容，所以要对待patch程序的<code>.eh_frame</code>段进行修改，直接将<code>hook</code>程序中的<code>.text</code>段的内容赋值到<code>.eh_frame</code>段的内容即可。赋值完成之后，在通过与前面一致的方法修改函数跳转地址，使其跳转到<code>.eh_frame</code>段来执行我们的hook代码</p>
<p>具体的代码如下：</p>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;amd64&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./vulner&quot;)
hook = lief.parse('./hook')

# write hook's .text content to binary's .eh_frame content 
sec_ehrame = binary.get_section('.eh_frame')
print sec_ehrame.content
sec_text = hook.get_section('.text')
print sec_text.content
sec_ehrame.content = sec_text.content
print binary.get_section('.eh_frame').content

# hook target call
dstaddr = sec_ehrame.virtual_address
srcaddr = 0x400584

patch_call(binary,srcaddr,dstaddr)

binary.write('vulner.patched')
</code></pre>
<p>直接将hook程序中的<code>.text</code>段的<code>content</code>赋值到binary程序中的<code>.eh_frame</code>段的<code>content</code>段得到的效果如下图所示，内容确实是我们的hook函数：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411220505.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411220505.png" alt="img" /></a></p>
<p>修改指定的函数调用，使其跳转到我们修改后的<code>.eh_frame</code>段来执行，效果如下图所示：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411223153.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190411223153.png" alt="img" /></a></p>
<h2 id="示例"><a class="header" href="#示例">示例</a></h2>
<p>容易造成栈溢出的函数</p>
<pre><code class="language-c">void * memcpy ( void * destination, const void * source, size_t num );
char * strcpy ( char * destination, const char * source );
char * strncpy ( char * destination, const char * source, size_t num );
char * gets(char*str);
ssize_t read(int fd, void *buf, size_t count);
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
char * fgets ( char * str, int num, FILE * stream );
char * strcat ( char * destination, const char * source );
scanf(“%20c”, &amp;s);
</code></pre>
<h3 id="read-patch"><a class="header" href="#read-patch">read patch</a></h3>
<p>read造成的栈溢出，直接修改第三个参数，限制输入大小。</p>
<p>others_babystack中，read存在栈溢出。</p>
<p>使用keypatch将第三个参数改为0x80即可。</p>
<p><strong>Edit -&gt; Patch program -&gt; Apply patches to input file</strong></p>
<p>将修改保存到一个新的二进制文件</p>
<p><img src="C:%5CUsers%5C16148%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1687963196606.png" alt="1687963196606" /></p>
<h3 id="gets-patch"><a class="header" href="#gets-patch">gets patch</a></h3>
<p>ret2text为例，32位程序。</p>
<p>gets造成栈溢出，程序没有read函数，构造syscall系统调用，<strong>注意32位程序系统调用为<code>int 0x80;</code>，64为程序为<code>syscall ;</code></strong></p>
<p>先从<code>call gets</code>跳到eh_frame构造系统调用处的。</p>
<pre><code class="language-c">void mygets(char *a,int b){
	// 32bits int 0x80;   64bits syscall;
	asm(
		&quot;mov $0x3,%eax\n&quot;
		&quot;mov $0, %ebx\n&quot;
		&quot;mov %eax, %ecx\n&quot;
		&quot;mov $0x20,%edx\n&quot;
		&quot;int $0x80\n&quot; 
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		);
}
//gcc -Os -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook_gets.c -o hook_gets


// 64bits
// void mygets(char *a,int b){
// 	// 32bits int 0x80;   64bits syscall;
// 	asm(
// 		&quot;mov $0x0,%rax\n&quot;
// 		&quot;mov %rdi, %rsi\n&quot;
// 		&quot;mov $0, %rdi\n&quot;
// 		&quot;mov $0x20,%rdx\n&quot;
// 		&quot;syscall\n&quot; 
// 		&quot;nop\n&quot;
// 		&quot;nop\n&quot;
// 		&quot;nop\n&quot;
// 		&quot;nop\n&quot;
// 		&quot;nop\n&quot;
		
// 		);
// }
</code></pre>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;i386&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./ret2text&quot;)
hook = lief.parse('./hook_gets')

# write hook's .text content to binary's .eh_frame content 
sec_ehrame = binary.get_section('.eh_frame')
print sec_ehrame.content
sec_text = hook.get_section('.text')
print sec_text.content
sec_ehrame.content = sec_text.content
print binary.get_section('.eh_frame').content

# hook target call
dstaddr = sec_ehrame.virtual_address
srcaddr = 0x080486AE
print(&quot;dstaddr ==&gt;&quot;, hex(dstaddr))
patch_call(binary,srcaddr,dstaddr)

binary.write('ret2text-patched')
</code></pre>
<h3 id="堆溢出"><a class="header" href="#堆溢出">堆溢出</a></h3>
<p>以0ctf_2017_babyheap为例，程序edit功能处，输入大小又用户重新输入，造成任意大小写。</p>
<pre><code class="language-c">__int64 __fastcall sub_E7F(__int64 a1)
{
  __int64 result; // rax
  int v2; // [rsp+18h] [rbp-8h]
  int v3; // [rsp+1Ch] [rbp-4h]

  printf(&quot;Index: &quot;);
  result = sub_138C();
  v2 = result;
  if ( (int)result &gt;= 0 &amp;&amp; (int)result &lt;= 15 )
  {
    result = *(unsigned int *)(24LL * (int)result + a1);
    if ( (_DWORD)result == 1 )
    {
      printf(&quot;Size: &quot;);
      result = sub_138C();
      v3 = result;
      if ( (int)result &gt; 0 )
      {
        printf(&quot;Content: &quot;);
        return sub_11B2(*(_QWORD *)(24LL * v2 + a1 + 16), v3); //v3为用户输入任意大小
      }
    }
  }
  return result;
}
</code></pre>
<p>这个我们把v3参数修改为堆块本身大小即可，根据堆块结构<code>(24LL * v2 + a1 + 8)</code>为堆块的size。</p>
<p>那么把v3修改为<code>(24LL * v2 + a1 + 8)</code></p>
<p>对应汇编代码如下：</p>
<p>需要修改rsi为<code>(24LL * v2 + a1 + 8)</code> ，即<code>mov rsi, [rax+8]</code></p>
<pre><code class="language-asm">.text:0000000000000F39                 mov     rax, [rax+10h]
.text:0000000000000F3D                 mov     rsi, rcx
.text:0000000000000F40                 mov     rdi, rax
.text:0000000000000F43                 call    sub_11B2
.text:0000000000000F48                 jmp     short locret_F4E
</code></pre>
<p><code>mov rsi, [rax+8]</code>占四字节，本身<code> mov rsi, rcx</code>指令占3字节，长度不够，所以跳转到<code>.eh_frame</code>段执行再跳转回来。</p>
<p>又由于<code>mov rax, [rax+10h]</code>修改了<code>rax</code>的值，所以<code>mov rax, [rax+10h]</code>与<code>mov rsi, [rax+8]</code>调换一下位置</p>
<p>patch方法：<strong>edit-&gt;Patch program-&gt;change byte</strong>输入十六进制机器码</p>
<pre><code class="language-asm">48 8B 70 08 48 8B 40 10 48 89 C7 E9 A3 F9 FF 
</code></pre>
<p>修改如下：</p>
<pre><code class="language-asm">.eh_frame:0000000000001590               loc_1590:                           
.eh_frame:0000000000001590 48 8B 70 08            mov     rsi, [rax+8]
.eh_frame:0000000000001594 48 8B 40 10            mov     rax, [rax+10h]
.eh_frame:0000000000001598 48 89 C7               mov     rdi, rax
.eh_frame:000000000000159B E9 A3 F9 FF FF         jmp     loc_F43       
</code></pre>
<pre><code class="language-asm">.text:0000000000000F39 E9 52 06 00 00             jmp     loc_1590        
.text:0000000000000F3E 90                         nop
.text:0000000000000F3F 90                         nop
.text:0000000000000F40 90                         nop
.text:0000000000000F41 90                         nop
.text:0000000000000F42 90                         nop
.text:0000000000000F43
.text:0000000000000F43      loc_F43:                         ; CODE XREF: sub_E7F+71C↓j
.text:0000000000000F43 E8 6A 02 00 00             call    sub_11B2
</code></pre>
<p>查看伪代码</p>
<pre><code class="language-c">....
.....
    if ( (_DWORD)result == 1 )
    {
      printf(&quot;Size: &quot;);
      result = sub_138C();
      if ( (int)result &gt; 0 )
      {
        printf(&quot;Content: &quot;);
        return sub_11B2(*(_QWORD *)(24LL * v2 + a1 + 16), *(_QWORD *)(24LL * v2 + a1 + 8));
.....
....
</code></pre>
<h3 id="off-by-nullone-patch"><a class="header" href="#off-by-nullone-patch">off-by-null/one patch</a></h3>
<p><code>b00ks</code>为例，题目中读取数据的函数会多读入2个字节的数据，程序在调用该函数时都将<code>size</code>减去了<code>1</code>，所以这里仍然会多读入一个字节，导致<code>off-by-null</code></p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413184702.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413184702.png" alt="img" /></a></p>
<p>所以，这里的目标就是在调用该函数之前，把它的第二个参数再次减去<code>1</code>，这样就不存在<code>off-by-null</code>漏洞了，调用该函数的地方有好几个，这里仅对其中的一个进行<code>hook</code>，就选取<code>edit</code>功能中调用该函数的地方进行<code>hook</code></p>
<p>待<code>hook</code>的call指令地址为<code>0xF2B</code></p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413185106.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413185106.png" alt="img" /></a></p>
<p>要将第二个参数减一，而第二个参数是存放在<code>rsi</code>寄存器中的，所以只需要将<code>rsi</code>的值减去一，接着直接调用函数<code>read_ndata</code>即可，而我们在<code>hook.c</code>中写hook函数时是不知道增加了<code>segment</code>之后函数<code>read_ndata</code>的地址是多少的，所以这里先采取用<code>5个nop</code>指令来占位置的方法为<code>call</code>指令占位</p>
<pre><code>int myread(char *ptr,int num){
	asm(
		&quot;sub $0x1,%rsi\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		&quot;nop\n&quot;
		);
	return 0;
}
</code></pre>
<p>将上述的<code>hook.c</code>进行编译，得到<code>hook</code>文件：</p>
<blockquote>
<p>gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook</p>
</blockquote>
<p>接着使用如下脚本将<code>0xF2B</code>处的<code>call</code>指令进行<code>hook</code></p>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;amd64&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./b00ks&quot;)
hook = lief.parse('./hook')
print hook.get_section('.text').content
# inject hook program to binary
segment_added  = binary.add(hook.segments[0])
hook_fun      = hook.get_symbol(&quot;myread&quot;)

# hook b00k's call 
dstaddr = segment_added.virtual_address + hook_fun.value
srcaddr = 0xf2b
patch_call(binary,srcaddr,dstaddr)

binary.write('b00ks-patched')
</code></pre>
<p>patch之后，把得到的<code>b00ks-patched</code>文件拖到<code>IDA</code>中进行分析，发现并没有将<code>edit</code>功能中的call指令指向我们的hook函数，而且该call指令的地址也由原来的<code>0xf2b</code>变成了<code>0x1f2b</code></p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190056.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190056.png" alt="img" /></a></p>
<p>是怎么回事呢？对比一下两个程序的段信息，发现patch之后的程序第一个段的大小增加了<code>0x1000</code>，导致后面的地址都增加了<code>0x1000</code>：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190609.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190609.png" alt="img" /></a></p>
<p>所以在增加了段之后我们需要修改的<code>call</code>指令地址已经不再是<code>0xf2b</code>，而变成了<code>0x1f2b</code>，所以对脚本稍作修改，把脚本中的<code>srcaddr = 0xf2b</code>改成<code>srcaddr = 0x1f2b</code>，再次查看patch的结果：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190956.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413190956.png" alt="img" /></a></p>
<p>可以看到该出的函数调用确实指向了我们的hook函数<code>sub_4042d8</code></p>
<pre><code>LOAD:00000000004042D8 sub_4042D8      proc near               ; CODE XREF: sub_1E17+114↑p
LOAD:00000000004042D8
LOAD:00000000004042D8 var_C           = dword ptr -0Ch
LOAD:00000000004042D8 var_8           = qword ptr -8
LOAD:00000000004042D8
LOAD:00000000004042D8                 push    rbp
LOAD:00000000004042D9                 mov     rbp, rsp
LOAD:00000000004042DC                 mov     [rbp+var_8], rdi
LOAD:00000000004042E0                 mov     [rbp+var_C], esi
LOAD:00000000004042E3                 sub     rsi, 1
LOAD:00000000004042E7                 nop
LOAD:00000000004042E8                 nop
LOAD:00000000004042E9                 nop
LOAD:00000000004042EA                 nop
LOAD:00000000004042EB                 nop
LOAD:00000000004042EC                 mov     eax, 0
LOAD:00000000004042F1                 pop     rbp
LOAD:00000000004042F2                 retn
LOAD:00000000004042F2 sub_4042D8      endp
</code></pre>
<ul>
<li>继续完善</li>
</ul>
<p>经过上面的操作，我们已经能够将<code>call</code>劫持到我们的hook函数来执行了，还差的就是把hook函数中<code>占位的nop指令</code>修改成<code>call read_ndata</code>函数，所以接下来将对其进行修改</p>
<p>观察上面patch后的结果，可以知道<code>nop</code>指令的起始地址为<code>0x4042E7</code>，我们要调用的函数<code>read_ndata</code>地址则变成了<code>0x19f5</code></p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413191719.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413191719.png" alt="img" /></a></p>
<p>所以直接如下设置<code>patch_call</code>的参数就能实现最终的patch：</p>
<pre><code>dstaddr = 0x19f5
srcaddr = 0x4042e7
</code></pre>
<p>完整的脚本如下：</p>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;amd64&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./b00ks&quot;)
hook = lief.parse('./hook')
print hook.get_section('.text').content
# inject hook program to binary
segment_added  = binary.add(hook.segments[0])
hook_fun      = hook.get_symbol(&quot;myread&quot;)

# hook b00k's call 
dstaddr = segment_added.virtual_address + hook_fun.value
srcaddr = 0x1f2b
patch_call(binary,srcaddr,dstaddr)

dstaddr = 0x19f5
srcaddr = 0x4042e7
patch_call(binary,srcaddr,dstaddr)

binary.write('b00ks-patched')
</code></pre>
<p>patch的效果如下所示：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413192115.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413192115.png" alt="img" /></a></p>
<pre><code>LOAD:00000000004042D8 ; Attributes: bp-based frame
LOAD:00000000004042D8
LOAD:00000000004042D8 sub_4042D8      proc near               ; CODE XREF: sub_1E17+114↑p
LOAD:00000000004042D8
LOAD:00000000004042D8 var_C           = dword ptr -0Ch
LOAD:00000000004042D8 var_8           = qword ptr -8
LOAD:00000000004042D8
LOAD:00000000004042D8                 push    rbp
LOAD:00000000004042D9                 mov     rbp, rsp
LOAD:00000000004042DC                 mov     [rbp+var_8], rdi
LOAD:00000000004042E0                 mov     [rbp+var_C], esi
LOAD:00000000004042E3                 sub     rsi, 1
LOAD:00000000004042E7                 call    sub_19F5
LOAD:00000000004042EC                 mov     eax, 0
LOAD:00000000004042F1                 pop     rbp
LOAD:00000000004042F2                 retn
LOAD:00000000004042F2 sub_4042D8      endp
__int64 __fastcall sub_4042D8(__int64 a1, __int64 a2)
{
  sub_19F5(a1, a2 - 1);
  return 0LL;
}
</code></pre>
<ul>
<li>通过.eh_frame段实现patch</li>
</ul>
<p>前面介绍的方法是通过在程序中增加一个段的方式来实现patch的，经过这种方法patch后虽然正常的执行都没有问题，但是程序的第一个段的大小增加了0x1000，这导致了程序中各个函数的地址也都增加了0x1000，对程序的改动较大，这里可以通过往<code>.eh_frame</code>段写入hook代码，然后跳转到这里执行的方式</p>
<p>过程和前面介绍的差不多，这里直接贴patch成功的脚本了</p>
<pre><code class="language-python">import lief
from pwn import *

def patch_call(file,srcaddr,dstaddr,arch = &quot;amd64&quot;):
	print hex(dstaddr)
	length = p32((dstaddr - (srcaddr + 5 )) &amp; 0xffffffff)
	order = '\xe8'+length
	print disasm(order,arch=arch)
	file.patch_address(srcaddr,[ord(i) for i in order])

binary = lief.parse(&quot;./b00ks&quot;)
hook = lief.parse('./hook')

# write hook's .text content to binary's .eh_frame content 
sec_ehrame = binary.get_section('.eh_frame')
# print sec_ehrame.content
sec_text = hook.get_section('.text')
sec_ehrame.content = sec_text.content


# hook target call
dstaddr = sec_ehrame.virtual_address
srcaddr = binary.get_section('.text').virtual_address+(0xf2b-0x8e0)
print 'srcaddr:'+hex(srcaddr)
print 'dstaddr:'+hex(dstaddr)

patch_call(binary,srcaddr,dstaddr)

# modify nop to call
dstaddr = binary.get_section('.text').virtual_address+(0x9f5-0x8e0)
srcaddr = sec_ehrame.virtual_address+0xf
patch_call(binary,srcaddr,dstaddr)

binary.write('b00ks-patched-frame')
</code></pre>
<p>patch的效果如下：</p>
<p><a href="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413210506.png"><img src="https://espem.oss-cn-beijing.aliyuncs.com/img/20190413210506.png" alt="img" /></a></p>
<p><strong>可以看到这种方式对程序的影响确实很小，在hook的代码很少的情况下，可以首选这种方法</strong></p>
<h3 id="整数溢出"><a class="header" href="#整数溢出">整数溢出</a></h3>
<p>有符号跳转改为无符号。</p>
<pre><code>无符号跳转：
JA ;无符号大于则跳转
JNA ;无符号不大于则跳转
JAE ;无符号大于等于则跳转 同JNB
JNAE ;无符号不大于等于则跳转 同JB
JB ;无符号小于则跳转
JNB ;无符号不小于则跳转
JBE ;无符号小于等于则跳转 同JNA
JNBE ;无符号不小于等于则跳转 同JA
有符号跳转：
JG ;有符号大于则跳转
JNG ;有符号不大于则跳转
JGE ;有符号大于等于则跳转 同JNL
JNGE ;有符号不大于等于则跳转 同JL
JL ;有符号小于则跳转
JNL ;有符号不小于则跳转
JLE ;有符号小于等于则跳转 同JNG
JNLE ;有符号不小于等于则跳转 同JG
</code></pre>
<h3 id="格式化字符串"><a class="header" href="#格式化字符串">格式化字符串</a></h3>
<p>程序里有puts的话把call printf改成call puts</p>
<p>增加代码，添加合适的参数，将printf(xxx)改为printf(“%s”,xxxxx)</p>
<p>增加代码，把printf改成write，没有write可以通过系统调用的形式。</p>
<p><strong>容易造成格式化字符串漏洞的函数</strong>：</p>
<pre><code>int printf ( const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
int sprintf ( char * str, const char * format, ... );
</code></pre>
<h3 id="命令执行"><a class="header" href="#命令执行">命令执行</a></h3>
<p>把命令执行函数nop掉</p>
<p><strong>容易造成命令执行的函数</strong>：</p>
<pre><code>FILE *popen(const char *command, const char *type);
int system(const char *command);
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
int execveat(int dirfd, const char *pathname, char *const argv[], char *const  envp[], int flags);
</code></pre>
<h3 id="不太优雅的方法"><a class="header" href="#不太优雅的方法"><del>不太优雅的方法</del></a></h3>
<p><strong>check脚本的时候有可能会检测</strong></p>
<p>把free的plt表改成ret~~</p>
<p><del>nop 掉 malloc</del></p>
<p><del>nop 掉 free</del></p>
<p><del>打乱got表</del></p>
<p>增加代码，在读的字节中过滤一些特殊的字符</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../posts/ctf/3.3_pwn HCTF2016 brop.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../posts/ctf/pwn_stack_overflow.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../posts/ctf/3.3_pwn HCTF2016 brop.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../posts/ctf/pwn_stack_overflow.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>



        <script>
            window.playground_line_numbers = true;
        </script>

        <script>
            window.playground_copyable = true;
        </script>

        <script src="../../ace.js"></script>
        <script src="../../editor.js"></script>
        <script src="../../mode-rust.js"></script>
        <script src="../../theme-dawn.js"></script>
        <script src="../../theme-tomorrow_night.js"></script>

        <script src="../../elasticlunr.min.js"></script>
        <script src="../../mark.min.js"></script>
        <script src="../../searcher.js"></script>

        <script src="../../clipboard.min.js"></script>
        <script src="../../highlight.js"></script>
        <script src="../../book.js"></script>

        <!-- Custom JS scripts -->
        <script src="../../src/js/custom.js"></script>


    </div>
    </body>
</html>
